package hxy.dragon.location_record.tencent;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;
import android.widget.Toast;

import androidx.core.app.NotificationCompat;
import androidx.preference.PreferenceManager;

import com.github.lany192.kv.KVUtils;
import com.tencent.map.geolocation.TencentLocation;
import com.tencent.map.geolocation.TencentLocationListener;
import com.tencent.map.geolocation.TencentLocationManager;
import com.tencent.map.geolocation.TencentLocationRequest;
import com.tencent.mmkv.MMKV;

import java.text.SimpleDateFormat;

import hxy.dragon.location_record.MainActivity;
import hxy.dragon.location_record.R;
import hxy.dragon.location_record.util.Constant;
import hxy.dragon.location_record.util.Time;


public class LocationService extends android.app.Service implements TencentLocationListener {

    private Long userId;
    private TencentLocationManager mLocationManager;
    private TencentLocationRequest tencentLocationRequest;
    /**
     * 实现一个INBinder接口
     */
    private final IBinder myBinder = new LocalBinder();
    private BroadcastReceiver receiver;

    /**
     * 刷新次数
     */
    private int times = 1;
    private StringBuilder sb;

    /**
     * 默认上报间隔 20分钟
     */
    private Long interval = 1000 * 60 * 20L;
    private String SharedPreferencesIntervalKey = "interval";


    private SharedPreferences pref;

    /**
     * 将该接口实现为一个继承Binder得内部类的对象！
     */
    public class LocalBinder extends Binder {
        //在内部类实现一个返回对象的方法
        public LocationService getService() {
            return LocationService.this;
        }
    }

    @Override
    public IBinder onBind(Intent arg0) {
        return myBinder;
    }


    @Override
    public void onCreate() {
        super.onCreate();
        Log.i("hxy-location", "tencent location start");
        MMKV.initialize(getBaseContext());
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        sendNotification(null, "服务启动成功");
        tencentLocationConfig();

        pref = getSharedPreferences("name", MODE_PRIVATE);
        SharedPreferences defaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
        this.userId = Long.parseLong(defaultSharedPreferences.getString("signature", "0"));
        this.interval = Long.parseLong(defaultSharedPreferences.getString("update_time", "1200000"));

        return super.onStartCommand(intent, flags, startId);
    }


    /**
     * 腾讯位置信息配置
     */
    private void tencentLocationConfig() {
        mLocationManager = TencentLocationManager.getInstance(this);
        // 设置定位周期(位置监听器回调周期)，用户可以自定义定位间隔，时间单位为毫秒，不得小于1000毫秒:
        // 配置文档  https://lbs.qq.com/mobile/androidLocationSDK/androidGeoGuide/androidGeoContinue
        if (interval < 100000) {
            interval = 2 * 60 * 1000L;
        }
        tencentLocationRequest = TencentLocationRequest
                .create()
                .setRequestLevel(TencentLocationRequest.REQUEST_LEVEL_ADMIN_AREA)
                .setInterval(interval)
                .setAllowDirection(true);
        mLocationManager.requestLocationUpdates(
                tencentLocationRequest
//                        .setIndoorLocationMode(true)
                , this, getMainLooper());

//        final int LOC_NOTIFICATIONID = 1;
//        mLocationManager.enableForegroundLocation(LOC_NOTIFICATIONID, buildNotification());

        // 广播监听，更新配置信息
        receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {

                long userIdLong = intent.getExtras().getLong(Constant.USER_ID, 0L);
                if (userIdLong > 10) {
                    userId = userIdLong;
                    KVUtils.get().putLong(Constant.USER_ID, userIdLong);
                }

                long intervalLong = intent.getExtras().getLong(Constant.INTERVAL, 0L);
                if (intervalLong > 10000L) {
                    interval = intervalLong;
                    tencentLocationRequest.setInterval(intervalLong);
                    SharedPreferences.Editor edit = pref.edit();
                    edit.putLong(SharedPreferencesIntervalKey, intervalLong);
                    edit.commit();
                }
                mLocationManager.requestLocationUpdates(tencentLocationRequest, LocationService.this, getMainLooper());
            }
        };
        IntentFilter filter = new IntentFilter(Constant.BroadCast.INTERVAL);
        registerReceiver(receiver, filter);

    }

    @Override
    public void onLocationChanged(TencentLocation location, int error, String reason) {
        Log.i("hxy-location", "tencent service start onLocationChanged" + reason);

        sb = new StringBuilder();

        if (error == TencentLocation.ERROR_OK) {
            long time = location.getTime();
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String date = df.format(time);
            String timeValue = Time.desplay(interval);

            sb.append("Latitude/纬度=").append(location.getLatitude())
                    .append("\nLongitude/经度=").append(location.getLongitude())
                    .append("\n精度=").append(location.getAccuracy())
                    .append("\n来源=").append(location.getProvider())
                    .append("\n地址=").append(location.getAddress())
                    .append("\n名称=").append(location.getName())
                    .append("\n速度=").append(location.getSpeed())
                    .append("\n时间=" + date)
                    .append("\n更新间隔=" + timeValue)
                    .append("\n已刷新次数=" + (times++) + "\n" + this.userId);

            Intent intent = new Intent(Constant.BROADCAST);
            intent.putExtra("Latitude", location.getLatitude());
            intent.putExtra("Longitude", location.getLongitude());
            intent.putExtra(Constant.LOCATION_INFO, sb.toString());
            intent.putExtra("msg", "当前口令为空！\n客户端必须使用口令，然后告诉监控端口令，口令一致方可完成监听。输入口令后，必须按返回键或者在近期任务清除，然后再次打开。\nMIUI关闭神隐模式！建议在近期任务中锁定。定位周期为8秒。");
            sendBroadcast(intent);
            // TencentLocation的信息复制到 LocationModel
            LocationModel locationModel = LocationModel.buildLocationModel(location, userId);

            sendNotification(location.getName(), location.getAddress());

            try {
                NetworkService.postToServer(locationModel);
                // TODO 上报成功之后应该显示下
            } catch (Exception e) {
                Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
            }
            return;

        } else if (error == TencentLocation.ERROR_NETWORK) {
            sb.append("网络没有连接，请打开GPS搜星定位！");
            //在Android 6.0 及以上的系统版本中，当位置开关关闭时，onStatusUpdate接口会返回name=wifi，status=5，该状态码说明位置开关关闭，此时无法进行Wi-Fi扫描。收到该状态码后，请及时提醒用户打开位置开关。
            final NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            Intent intent = new Intent(Settings.ACTION_SETTINGS);
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
            builder.setContentTitle("腾讯定位").setSmallIcon(R.drawable.ic_launcher_background).setContentText("请打开网络或者GPS！").setAutoCancel(true);
            builder.setDefaults(NotificationCompat.PRIORITY_DEFAULT).setContentIntent(PendingIntent.getActivity(getApplicationContext(), 0, intent, 0));
            builder.setFullScreenIntent(PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT), true);
            Notification notification = builder.build();
            final int notifyId = 0x12345;
            notificationManager.notify(notifyId, notification);
        } else if (error == TencentLocation.ERROR_BAD_JSON) {
            sb.append("GPS, Wi-Fi 或基站错误引起的定位失败，请授予软件需要的权限。");
        } else if (error == TencentLocation.ERROR_UNKNOWN) {
            sb.append("定位失败，原因未知！");
        } else
            sb.append("定位失败，原因未知！");

        sendNotification("定位失败", times + ". " + reason);
        Intent intent = new Intent("com.hxy.location.service.broadcast");
        intent.putExtra("Latitude", location.getLatitude());
        intent.putExtra("Longitude", location.getLongitude());
        intent.putExtra(Constant.LOCATION_INFO, sb.toString());
        intent.putExtra("msg", "当前口令：" + "\n来自Service的广播消息：\n" + String.valueOf(sb) + "\n\n以上数据由后台Service工作采集，通过广播发送至显示Activity，保证Activity退出也不会停止定位，从而保证程序可以在后台一直监听手机位置。MIUI关闭神隐模式！建议在近期任务中锁定。定位周期为8秒。");
        sendBroadcast(intent);
    }


    @Override
    public void onStatusUpdate(String name, int status, String desc) {
        Log.i("hxy-location", "tencent service start onStatusUpdate" + name);

        if (WIFI.equalsIgnoreCase(name) && status == STATUS_LOCATION_SWITCH_OFF) {
            //在Android 6.0 及以上的系统版本中，当位置开关关闭时，onStatusUpdate接口会返回name=wifi，status=5，该状态码说明位置开关关闭，此时无法进行Wi-Fi扫描。收到该状态码后，请及时提醒用户打开位置开关。
            final NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            Intent intent = new Intent(Settings.ACTION_SETTINGS);
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
            builder.setContentTitle("你的位置").setSmallIcon(R.drawable.ic_launcher_background).setContentText("请打开网络或者GPS！").setAutoCancel(true);
            builder.setDefaults(NotificationCompat.PRIORITY_DEFAULT).setContentIntent(PendingIntent.getActivity(getApplicationContext(), 0, intent, 0));
            builder.setFullScreenIntent(PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT), true);
            Notification notification = builder.build();
            notificationManager.notify(0x12345, notification);
            Toast.makeText(this, "wifi异常，网络异常", Toast.LENGTH_SHORT).show();
            sendNotification("定位异常", "wifi异常，网络异常");
        }
    }


    private NotificationManager notificationManager;
    boolean isCreateChannel = true;
    private String NOTIFICATION_CHANNEL_NAME = "Tencent";

    /**
     * 这个好像没有什么用，没有生效
     *
     * @return
     */
    @Deprecated
    private Notification buildNotification() {
        Notification.Builder builder = null;
        Notification notification = null;
        if (android.os.Build.VERSION.SDK_INT >= 26) {
            //Android O上对Notification进行了修改，如果设置的targetSDKVersion>=26建议使用此种方式创建通知栏
            if (notificationManager == null) {
                notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            }
            String channelId = getPackageName();
            if (!isCreateChannel) {
                NotificationChannel notificationChannel = new NotificationChannel(channelId,
                        NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
                notificationChannel.enableLights(true);//是否在桌面icon右上角展示小圆点
                notificationChannel.setLightColor(Color.BLUE); //小圆点颜色
                notificationChannel.setShowBadge(true); //是否在久按桌面图标时显示此渠道的通知
                notificationManager.createNotificationChannel(notificationChannel);
                isCreateChannel = true;
            }
            builder = new Notification.Builder(getApplicationContext(), channelId);
        } else {
            builder = new Notification.Builder(getApplicationContext());
        }
        builder.setSmallIcon(R.drawable.ic_launcher_background)
                .setContentTitle("LocationDemo")
                .setContentText("正在后台运行")
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_background))
                .setWhen(System.currentTimeMillis());

        if (android.os.Build.VERSION.SDK_INT >= 16) {
            notification = builder.build();
        } else {
            notification = builder.getNotification();
        }
        return notification;
    }

    /**
     * Android8之后必须要的
     *
     * @link https://blog.csdn.net/NewActivity/article/details/103243124
     */
    private void sendNotification(String title, String content) {
        if (title == null) {
            title = getResources().getString(R.string.app_name);
        }
        if (content == null) {
            content = getResources().getString(R.string.notice_info);
        }

        String CHANNEL_ID = "hxy.dragon.location";
        String CHANNEL_NAME = "后台服务";
        NotificationChannel notificationChannel = null;
        NotificationCompat.Builder builder = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            notificationChannel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
            NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            notificationManager.createNotificationChannel(notificationChannel);
        }

        Intent intent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
        builder = new NotificationCompat.Builder(this, CHANNEL_ID).
                setContentTitle(title).
                setContentText(content).
                setWhen(System.currentTimeMillis()).
                setSmallIcon(R.mipmap.ic_launcher).
                setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher)).
                setContentIntent(pendingIntent).setDefaults(NotificationCompat.FLAG_ONGOING_EVENT)
                .setPriority(Notification.PRIORITY_MAX);


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//SDK版本>=21才能设置悬挂式通知栏
            builder.setCategory(String.valueOf(Notification.FLAG_ONGOING_EVENT))
                    .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
                    .setColor(getResources().getColor(R.color.white));
            Intent intent2 = new Intent();
            PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent2, 0);
            builder.setFullScreenIntent(pi, true);
        }
        Notification notification = builder.build();
        startForeground(1, notification);
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        if (receiver != null) {
            unregisterReceiver(receiver);//LS:重点！
        }
        Toast.makeText(this, "LocationService onDestroy", Toast.LENGTH_SHORT).show();
    }

}


